<template>
  <div class="diagram">
    <div class="diagram-main">
      <!-- 菜单 栏 -->
      <!-- <diagram-sidebar class="diagram-sidebar" @collectTable="collectTableState"/> -->
      <!-- 数据采集表 -->
      <!-- <div class="CollectTableBox" v-show="receivedMessage.state=='4'">
        <DataCollectTable />
      </div> -->
      <!-- 节点详情 -->
       <div class="nodeDetailBox" v-show="receivedMessage.state!='4'&&nodeDetaillogVisible">
        <div class="collect-title"><img :src="img.iconM" alt=""> {{ title }}</div>
        <Nodepreview class="nodePreview" :currentRowData="activeNodes[0]"
          :pageStatus="nodeDetailState" @nodeIndex="nodeIndex" />
      </div>
      <!-- 力量构成 -->
      <div class="diagram-container" ref="container" v-show="receivedMessage.state!='4'&&!nodeDetaillogVisible">
        <diagram-toolbar class="diagram-toolbar" v-if="lf" :lf="lf" :activeEdges="activeEdges"
          @changeNodeFillColor="$_changeNodeFill" @saveGraph="$_saveGraph" />
        <div class="diagram-wrapper">
          <div class="tuglie">
            <div class="tuglieTitle">关系</div>
            <div>
              <img :src="img.zhjt" alt="">
              <span>指挥关系</span>
            </div>
            <div>
              <img :src="img.zcjt" alt="">
              <span>组成关系</span>
            </div>
            <div>
              <img :src="img.xtjt" alt="">
              <span>协同关系</span>
            </div>
          </div>
          <div class="lf-diagram" ref="diagram"></div>
        </div>
      </div>
    </div>
    <!-- 右侧属性面板 -->
    <PropertyPanel class="diagram-panel" v-if="(activeNodes.length > 0 || activeEdges.length > 0 ) && receivedMessage.state!='4' && !nodeDetaillogVisible"
      :onlyEdge="activeNodes.length === 0" :elementsStyle="properties" @setStyle="$_setStyle"
      @setZIndex="$_setZIndex" />
  </div>
</template>

<script>
import LogicFlow from '@logicflow/core'
// 插件（也可以叫组件）(此处引入 框选，拖拽，菜单)
import { SelectionSelect, DndPanel, Menu } from '@logicflow/extension'
import '@logicflow/core/lib/style/index.css'
import '@logicflow/extension/lib/style/index.css'
import DiagramToolbar from './DiagramToolbar.vue'
import DiagramSidebar from './DiagramSidebarMenu.vue'
import PropertyPanel from './PropertyPanel.vue'
import DataCollectTable from './dataCollectTable.vue'
import Nodepreview from './nodePreview/index.vue'
import { registerCustomElement } from './node'
import { getList } from '@/api/api'
import zhjt from '@/assets/images/zhjt.png'
import zcjt from '@/assets/images/zcjt.png'
import xtjt from '@/assets/images/xtjt.png'
import iconM from '@/assets/images/iconMini.png'

export default {
  name: 'Diagram',
    components: {
    DiagramToolbar,
    DiagramSidebar,
    PropertyPanel,
    DataCollectTable,
    Nodepreview
  },
  data() {
    return {
      img: {
        zhjt,
        zcjt,
        xtjt,
        iconM
      },
      title: '',
      nodeDetaillogVisible: false,
      nodeDetailState: 'edit',
      sidebarWidth: 200,
      diagramWidth: 0,
      diagramHeight: 0,
      lf: '',
      filename: '',
      activeNodes: [],
      activeEdges: [],
      properties: {},
      receivedMessage: {},//接收菜单传来的消息
    }
  },
  created() {
    // this.getListUser();
  },
  mounted() {
    let data = {}
    if (window.location.search) {
      const query = window.location.search.substring(1).split('&').reduce((map, kv) => {
        const [key, value] = kv.split('=')
        map[key] = value
        return map
      }, {})
      this.filename = query.filename
      const d = window.sessionStorage.getItem(this.filename)
      if (d) {
        data = JSON.parse(d)
      }
    }
    this.initLogicFlow(data)
  },
  watch: {
    siderbarMsg(val) {
      this.title = val
      // console.log(this.title)
    }
  },
  computed: {
    // 获取当前选中的元素
    // currentElement() {
    //   return this.activeNodes[0] || this.activeEdges[0]
    // },
    siderbarMsg() {
      return this.$store.getters.getNodeStatus;
    }
  },
  methods: {
    initLogicFlow(data) {
      // 引入框选插件
      LogicFlow.use(SelectionSelect)
      LogicFlow.use(DndPanel);
      LogicFlow.use(Menu);
      const lf = new LogicFlow({
        container: this.$refs.diagram,
        overlapMode: 1,
        autoWrap: true,
        metaKeyMultipleSelected: true,
        keyboard: {
          enabled: true
        },
        grid: {
          visible: false,
          size: 5
        },
        background: {
          // backgroundImage: 'url("")',
          backgroundRepeat: 'repeat'
        }
      })
      lf.setTheme(
        {
          //设置默认节点样式
          baseNode: { strokeWidth: 1 },
          //设置矩形节点样式
          rect: {
            fill: "#144057", // 填充颜色
            stroke: "#1cd3ff", // 边框颜色
            strokeWidth: 2, // 边框宽度
            rx: 5, //圆角
            ry: 5,
          },
          //设置节点文本样式
          nodeText: {
            color: "#fff", // 文本颜色
            overflowMode: "autoWrap", // 超出后的处理方式
            lineHeight: 1.5, // 行高
            fontSize: 16, // 字体大小
          },
          //设置默认边样式
          baseEdge: {
            stroke: "#1cd3ff",  // 连线颜色
            strokeWidth: 2, // 连线宽度
          },
          //设置默认边文本样式
          edgeText: { overflowMode: 'autoWrap', lineHeight: 1.5 },//设置默认边样式
          //  edgeText: {
          //   textWidth: 100,
          //   overflowMode: "default",
          //   fontSize: 12,
          //   background: {
          //     fill: "#FFFFFF",
          //   },
          //锚点间建立连线时的样式
          anchorLine: {
            stroke: "#355f72",
            strokeWidth: 2,
            strokeDasharray: "3,2",
          },
        }
      )
      // 注册自定义元素
      registerCustomElement(lf)
      lf.setDefaultEdgeType('pro-polyline')
      lf.render(data)
      this.lf = lf
      this.lf.on('selection:selected,node:click,blank:click,edge:click', () => {
        this.$nextTick(() => {
          const { nodes, edges } = this.lf.getSelectElements()
          this.$set(this, 'activeNodes', nodes)
          this.activeNodes = nodes
          this.activeEdges = edges
          this.$_getProperty()
        })
      })
      // // 注册一个事件监听器，在节点即将添加时设置其大小
      // lf.on('node:dnd-add', (node) => {
      //   console.log(node)
      //     node.data.properties.width = 180;
      //     node.data.properties.height = 50;
      // });
      // 注册拖拽插件节点
      this.lf.setPatternItems([
        {
          type: 'rect-radius',// 节点类型 圆角矩形
          text: '节点名称',// 默认节点名称
          label: '',// 拖拽面板节点文本描述
          // className: 'import_icon',
          // 自定义属性，用于存储需要这个节点携带的信息，可以传入宽高以重设节点的宽高
          //这里暂时禁用，原因是此处设置后，不能拖拽节点去调节矩形节点大小
          properties: {
            // width: 180,
            // height: 50,
          }
        },
      ])
      let that = this
      // 注册节点右键和线（边）右键菜单
      this.lf.addMenuConfig({
        // 节点右键菜单
        nodeMenu: [
          {
            text: '编辑详情',
            callback() {
              that.nodeDetaillogVisible = true
              // that.currentRowData = that.lf.getModelById(that.lf.getSelectedId())
            },
          },
          {
            text: '属性',
            callback(node) {
              that.$_alert(node)
              // alert(`
              //   节点id：${node.id}
              //   节点类型：${node.type}
              //   节点坐标：(x: ${node.x}, y: ${node.y})
              // `);
            },
          },
        ],
        // 边右键菜单
        edgeMenu: [
          {
            text: '属性',
            callback(edge) {
              const {
                id,
                type,
                startPoint,
                endPoint,
                sourceNodeId,
                targetNodeId,
              } = edge;
              that.$alert(`
               线id：${id}<br>
                线类型：${type}<br>
                线起点坐标：(startPoint: [${startPoint.x}, ${startPoint.y}])<br>
                线终点坐标：(endPoint: [${endPoint.x}, ${endPoint.y}])<br>
                源节点id：${sourceNodeId}<br>
                目标节点id：${targetNodeId}<br>
              `, '连线属性', {
                dangerouslyUseHTMLString: true,

              });
              // alert(`
              //   边id：${id}
              //   边类型：${type}
              //   边起点坐标：(startPoint: [${startPoint.x}, ${startPoint.y}])
              //   边终点坐标：(endPoint: [${endPoint.x}, ${endPoint.y}])
              //   源节点id：${sourceNodeId}
              //   目标节点id：${targetNodeId}
              // `);
            },
          },
        ],
        graphMenu: [
          {
            text: '分享',
            callback() {
              alert('分享成功！');
            },
          },
        ],
      });
      // 查找具有 .lf-dndpanel 元素
      const panel = document.querySelector('.lf-dndpanel');

      if (panel) {
        const newDiv = document.createElement('div');
        newDiv.textContent = '元素';
        newDiv.classList.add('lfdndtitle');

        // 添加到容器内
        panel.appendChild(newDiv);
      } else {
        console.warn('未找到 lf-dndpanel 元素');
      }
    },
    //获取节点属性
    $_alert(node) {
      this.$alert(`
                节点id：${node.id}<br>
                节点类型：${node.type}<br>
                节点坐标：(x: ${node.x}, y: ${node.y})
              `, '节点属性', {
        dangerouslyUseHTMLString: true,

      });
    },
    // 获取可以进行设置的属性
    $_getProperty() {
      let properties = {}
      const { nodes, edges } = this.lf.getSelectElements()
      nodes.forEach(node => {
        properties = { ...properties, ...node.properties }
      })
      edges.forEach(edge => {
        properties = { ...properties, ...edge.properties }
      })
      this.properties = properties
      return properties
    },
    // 节点拖入(上方引入了拖拽插件，此处暂时废弃不用)
    $_dragInNode(type) {
      this.lf.dnd.startDrag({
        type
      })
    },
    $_changeNodeFill(color) {
      const { nodes } = this.lf.graphModel.getSelectElements()
      nodes.forEach(({ id }) => {
        this.lf.setProperties(id, {
          fill: color
        })
      })
    },
    $_setStyle(item) {
      this.activeNodes.forEach(({ id }) => {
        this.lf.setProperties(id, item)
      })
      this.activeEdges.forEach(({ id }) => {
        this.lf.setProperties(id, item)
      })
      this.$_getProperty()
    },
    $_setZIndex(type) {
      this.activeNodes.forEach(({ id }) => {
        this.lf.setElementZIndex(id, type)
      })
      this.activeEdges.forEach(({ id }) => {
        this.lf.setElementZIndex(id, type)
      })
    },
    $_saveGraph() {
      const data = this.lf.getGraphData()
      this.download(this.filename, JSON.stringify(data))
    },
    download(filename, text) {
      window.sessionStorage.setItem(filename, text)
      const element = document.createElement('a')
      element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
      element.setAttribute('download', filename)
      element.style.display = 'none'
      document.body.appendChild(element)
      element.click()
      document.body.removeChild(element)
    },
    getListUser() {
      getList({ state: 2 }).then(res => {
        // if (res.code != 200) {
        //   this.$message.error(res.msg);
        //   return;
        // }
        //  this.$message.success(res);
        console.log(res)
      });
    },
    //判断是否点的是采集表
    collectTableState(message){
      this.receivedMessage = message;
    },
    //判断是否关闭详情编辑页面
    nodeIndex(message){
      this.nodeDetaillogVisible = message.state;
    }

  },
}
</script>

<style scoped>
.diagram {
  width: 100%;
  height: 100%;
}

.diagram * {
  box-sizing: border-box;
}

.diagram-toolbar {
  /* position: absolute; */
  top: 0;
  left: 264px;
  height: 40px;
  width: 100%;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #e5e5e5;
  z-index: 10;
  background: #e5e5e5;
}


.diagram-panel {
  width: 300px;
  background: var(--form-bg);
  height: calc(100vh - 114px);
  position: absolute;
  right: 30px;
  top: 79px;
  border: 1px solid var(--bigborder-color);
}

.diagram-container {
  flex: 1;
}

/* 由于背景图和gird不对齐，需要css处理一下 */
.diagram /deep/ .lf-background {
  left: -9px;
}

.diagram-wrapper {
  box-sizing: border-box;
  width: 100%;
  /* height: 100%; */
  margin-top: 10px;
  position: relative;
}

.lf-diagram {
  border: 1px solid var(--bigborder-color);
  width: 100%;
  height: calc(100vh - 114px);
}

::-webkit-scrollbar {
  width: 9px;
  height: 9px;
  background: white;
  border-left: 1px solid #e8e8e8;
}

::-webkit-scrollbar-thumb {
  border-width: 1px;
  border-style: solid;
  border-color: #fff;
  border-radius: 6px;
  background: #c9c9c9;
}

::-webkit-scrollbar-thumb:hover {
  background: #b5b5b5;
}

::v-deep .lf-dndpanel {
  background: #142639;
  border: 1px solid var(--bigborder-color);
  border-radius: 2px;
  padding: 15px;
  padding-top: 50px;

}

::v-deep .lf-dnd-shape {
  background: rgba(28, 211, 255, .2);
  border: 1px solid #1cd3ff;
  height: 32px;
  width: 80px;
}

::v-deep .lf-dnd-text {
  color: var(--title);
}

.tuglie {
  display: flex;
  flex-direction: column;
  padding: 16px;
  position: absolute;
  z-index: 10;
  top: 117px;
  left: 6px;
  border: 1px solid var(--bigborder-color);
  background: #142639;
  padding-top: 45px;
}

.tuglieTitle {
  text-align: center;
  border-bottom: 1px solid var(--bigborder-color);
  position: absolute;
  width: 100%;
  left: 0;
  top: 0;
  padding: 8px 0 !important;
}

.tuglie div {
  padding: 15px 0;
  display: flex;
  flex-direction: column;
}

.tuglie div img {
  width: 80px;
  margin-bottom: 10px;
}

::v-deep .lfdndtitle {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, 0);
  width: 100%;
  text-align: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-color);
}
.CollectTableBox{
  width: 100%;
}
.collect-title {
  font-size: 20px;
  /* margin-top: 10px; */
}
</style>